import _12师兄的论文.process.utils.csi as csi
import matplotlib.pyplot as plt
import numpy as np
import os
import csv

class File_Helper:

    def write_or_append_file(self, content, path, type='w'):
        assert content is not None and path is not None
        with open(path, type) as f:
            f.write(content)
            f.close()

    def is_exist(self, list, name):
        p = name.rfind('.')
        name = name[:p] + '.csv'
        for e in list:
            if e == name:
                print('skip', name)
                return True
        return False


    def convert_to_csv(self, root_path, is_return_all_ntx=False):
        '''
        :param root_path: 传入根目录，将目录下所有.dat文件转为相同文件名的csv文件
        '''
        list = os.listdir(root_path)
        filenames = [dir for dir in list if dir.endswith('.dat') and not self.is_exist(list, dir)]

        for fn in filenames:
            path = root_path + '/' + fn
            data = csi.load_data(path, is_return_raw=False, is_return_all_ntx=is_return_all_ntx)
            # 这里由于是三维的(ntx, subscarrier, samples)所以需要reshape下
            data = data.reshape(data.shape[0] * data.shape[1], -1)
            print(data.shape)
            p = fn.rfind('.')
            new_fn = root_path + '/' + fn[:p] + '.csv'
            np.savetxt(new_fn, data, delimiter=',')

    def load_csv_and_extract_wave(self, root_path, is_show_figure=True):
        '''
        :param root_path: 根目录，扫描目录下所有的csv文件
        :param DWT: 是否需要直接DWT压缩
        :return: 返回一个map，包含每个用户的每个手势的每个样本中的有效提取波形段,返回的数据都是list类型，没有numpy类型
        '''
        filenames = [dir for dir in os.listdir(root_path) if dir.endswith('.csv')]
        users = {}
        for fn in filenames:
            split = fn.split('_')
            type = split[0]  # 手指类型
            user = split[1]  # 哪个用户
            if not user in users.keys():
                users[user] = {}
            if not type in users[user].keys():
                users[user][type] = {
                    'data': [],
                    'label': [],
                    'path':[]
                }

            path = root_path + '/' + fn
            print('当前路径：', path)
            data = np.loadtxt(path, dtype=np.float, delimiter=',')
            data = data.reshape(data.shape[0] // 90, 90, -1)
            print(data.shape)
            res = csi.get_multi_wave(data, figure_show=is_show_figure) # 返回一个数组，包含提取的有效波形段
            # res = csi.solve_data(data, figure_show=is_show_figure) # 返回一个数组，包含提取的有效波形段
            print(len(res))
            # res = csi.get_single_wave(data, figure_show=is_show_figure) # 使用KNN的方式
            # print(len(res[0]))
            label = [] #记录当前wave的label
            # if DWT:
            #     l = []
            #     for wave in res:
            #         if is_show_figure:
            #             plt.plot(wave)
            #             plt.show()
            #         ca, cb = csi.dwt(wave)
            #         if is_show_figure:
            #             plt.plot(ca)
            #             plt.show()
            #         l.append(ca.tolist())
            #         label.append(int(type[-1]))
            #     res = l
            # else:
            for wave in res:
                label.append(int(type[-1]))
            for i in range(len(res)):
                users[user][type]['data'].append(res[i])
                users[user][type]['label'].append(label[i])
                users[user][type]['path'].append(path)
        return users


    def write_extracted_feature_to_csv(self, users_data, path):
        '''
        输出到文本的格式为：[用户名,按键类型,标签,数据...]
        :param users_data: 用户数据map
        :param path: 输出路径
        '''
        assert users_data is not None and path is not None

        self.write_or_append_file('', path, type='w')
        # print(users_data)
        for user in users_data: #用户
            for type in users_data[user]: #按键类型
                content = user + ',' + type
                for i in range(len(users_data[user][type]['data'])): #当前按键类型多少个
                    wave = users_data[user][type]['data'][i]
                    label = users_data[user][type]['label'][i]
                    p = users_data[user][type]['path'][i]
                    string = content + ',' + str(label) + ',' + p
                    for v in wave:
                        string += ',' + str(v)
                    string += '\n'
                    self.write_or_append_file(string, path, type='a')


    def load_extracted_feature_from_csv(self, path, feature_row=1):
        '''
        :param path: 路径
        :param feature_row 特征行有几个，默认一个表示一行为一个波形特征。像CNN可以2行卷积进行特征提取
        :return: 返回训练集的数据和label
        '''
        assert path is not None
        reader = csv.reader(open(path, 'r'))
        x_data, y_data, z_data = [], [], []
        features = []
        for row in reader:
            if feature_row == 1:
                x_data.append([float(i) for i in row[4:]])
                y_data.append(int(row[2]))
                z_data.append(row[3])
            else:
                features.append([float(i) for i in row[4:]])
                if len(features) == feature_row:
                    x_data.append(features)
                    y_data.append(int(row[2]))
                    z_data.append(row[3])
                    features = []

        return x_data, y_data, z_data

